#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import time
import json
from datetime import datetime
import threading
from concurrent.futures import ThreadPoolExecutor, as_completed
import statistics

class ConcurrentHAITest:
    def __init__(self, base_url='http://localhost:8080'):
        self.base_url = base_url
        self.creation_times = []
        self.destruction_times = []
        self.created_instances = []
        self.lock = threading.Lock()
    
    def create_single_instance(self, instance_num):
        """创建单个实例并记录时间"""
        print(f'🚀 开始创建实例 {instance_num}/10...')
        start_time = time.time()
        
        try:
            # 创建实例
            response = requests.post(f'{self.base_url}/api/v1/servers', 
                                   json={'region': 'ap-beijing', 'gpu_type': 'basic'}, 
                                   timeout=10)
            
            if response.status_code == 200:
                result = response.json()
                if result.get('success'):
                    instance_id = result.get('instance_id')
                    print(f'  📝 实例 {instance_num} ID: {instance_id}')
                    
                    # 等待实例真正创建完成
                    print(f'  ⏳ 实例 {instance_num} 等待创建完成...')
                    
                    # 检查实例状态，直到状态为RUNNING
                    max_wait_time = 300  # 最多等待5分钟
                    check_interval = 10   # 每10秒检查一次
                    wait_time = 0
                    
                    while wait_time < max_wait_time:
                        time.sleep(check_interval)
                        wait_time += check_interval
                        
                        # 检查实例状态
                        try:
                            status_response = requests.get(f'{self.base_url}/api/v1/servers', timeout=10)
                            if status_response.status_code == 200:
                                status_data = status_response.json()
                                if status_data.get('success'):
                                    servers = status_data['data']
                                    instance_status = None
                                    for server in servers:
                                        if server['instance_id'] == instance_id:
                                            instance_status = server['status']
                                            break
                                    
                                    if instance_status == 'RUNNING':
                                        end_time = time.time()
                                        creation_time = end_time - start_time
                                        
                                        with self.lock:
                                            self.creation_times.append(creation_time)
                                            self.created_instances.append(instance_id)
                                        
                                        print(f'  ✅ 实例 {instance_num} 创建完成: {creation_time:.1f}秒 ({creation_time/60:.1f}分钟)')
                                        return instance_id, creation_time, True
                                    else:
                                        print(f'  ⏳ 实例 {instance_num} 状态: {instance_status}, 等待中... ({wait_time}秒)')
                        except Exception as e:
                            print(f'  ❌ 实例 {instance_num} 状态检查失败: {e}')
                    
                    print(f'  ⚠️ 实例 {instance_num} 创建超时: {instance_id}')
                    return instance_id, None, False
                else:
                    print(f'  ❌ 实例 {instance_num} 创建失败: {result.get("error")}')
                    return None, None, False
            else:
                print(f'  ❌ 实例 {instance_num} 请求失败: {response.status_code}')
                return None, None, False
        except Exception as e:
            print(f'  ❌ 实例 {instance_num} 异常: {e}')
            return None, None, False
    
    def destroy_single_instance(self, instance_id, instance_num, total):
        """销毁单个实例并记录时间"""
        print(f'🗑️ 销毁实例 {instance_num}/{total}: {instance_id}...')
        start_time = time.time()
        
        try:
            destroy_response = requests.delete(f'{self.base_url}/api/v1/servers/{instance_id}', timeout=60)
            end_time = time.time()
            
            if destroy_response.status_code == 200:
                result = destroy_response.json()
                if result.get('success'):
                    destruction_time = end_time - start_time
                    
                    with self.lock:
                        self.destruction_times.append(destruction_time)
                    
                    print(f'  ✅ 实例 {instance_num} 销毁成功: {destruction_time:.1f}秒')
                    return True
                else:
                    print(f'  ❌ 实例 {instance_num} 销毁失败: {result.get("error")}')
                    return False
            else:
                print(f'  ❌ 实例 {instance_num} 请求失败: {destroy_response.status_code}')
                return False
        except Exception as e:
            print(f'  ❌ 实例 {instance_num} 异常: {e}')
            return False
    
    def concurrent_creation_test(self, num_instances=10):
        """并发创建测试"""
        print('🧪 开始并发HAI实例创建测试')
        print('=' * 60)
        print(f'测试开始时间: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}')
        print(f'并发创建实例数量: {num_instances}')
        print()
        
        # 使用线程池并发创建实例
        with ThreadPoolExecutor(max_workers=num_instances) as executor:
            # 提交所有创建任务
            future_to_num = {
                executor.submit(self.create_single_instance, i+1): i+1 
                for i in range(num_instances)
            }
            
            # 等待所有任务完成
            for future in as_completed(future_to_num):
                instance_num = future_to_num[future]
                try:
                    instance_id, creation_time, success = future.result()
                    if success:
                        print(f'🎯 实例 {instance_num} 完成: {instance_id} ({creation_time:.1f}秒)')
                    else:
                        print(f'❌ 实例 {instance_num} 失败')
                except Exception as e:
                    print(f'❌ 实例 {instance_num} 执行异常: {e}')
        
        print(f'\n📊 并发创建阶段完成')
        print(f'成功创建: {len(self.created_instances)} 个实例')
        print(f'创建时间统计:')
        if self.creation_times:
            avg_time = statistics.mean(self.creation_times)
            min_time = min(self.creation_times)
            max_time = max(self.creation_times)
            median_time = statistics.median(self.creation_times)
            std_time = statistics.stdev(self.creation_times) if len(self.creation_times) > 1 else 0
            
            print(f'  平均时间: {avg_time:.1f}秒 ({avg_time/60:.1f}分钟)')
            print(f'  中位数时间: {median_time:.1f}秒 ({median_time/60:.1f}分钟)')
            print(f'  最短时间: {min_time:.1f}秒 ({min_time/60:.1f}分钟)')
            print(f'  最长时间: {max_time:.1f}秒 ({max_time/60:.1f}分钟)')
            print(f'  标准差: {std_time:.1f}秒')
            
            # 显示每个实例的详细时间
            print(f'\n📋 各实例创建时间详情:')
            for i, (instance_id, time_taken) in enumerate(zip(self.created_instances, self.creation_times), 1):
                print(f'  实例 {i}: {instance_id} - {time_taken:.1f}秒')
        
        return self.created_instances, self.creation_times
    
    def concurrent_destruction_test(self):
        """并发销毁测试"""
        print(f'\n⏳ 等待5秒后开始并发销毁测试...')
        time.sleep(5)
        
        print('\n🗑️ 开始并发销毁所有HAI实例')
        print('-' * 40)
        
        if not self.created_instances:
            print('❌ 没有实例需要销毁')
            return []
        
        print(f'准备销毁 {len(self.created_instances)} 个实例')
        
        # 使用线程池并发销毁实例
        with ThreadPoolExecutor(max_workers=len(self.created_instances)) as executor:
            # 提交所有销毁任务
            future_to_info = {
                executor.submit(self.destroy_single_instance, instance_id, i+1, len(self.created_instances)): (instance_id, i+1)
                for i, instance_id in enumerate(self.created_instances)
            }
            
            # 等待所有任务完成
            success_count = 0
            fail_count = 0
            
            for future in as_completed(future_to_info):
                instance_id, instance_num = future_to_info[future]
                try:
                    success = future.result()
                    if success:
                        success_count += 1
                    else:
                        fail_count += 1
                except Exception as e:
                    print(f'❌ 实例 {instance_num} 销毁执行异常: {e}')
                    fail_count += 1
        
        print(f'\n📊 并发销毁阶段完成')
        print(f'成功销毁: {success_count} 个')
        print(f'销毁失败: {fail_count} 个')
        print(f'销毁时间统计:')
        if self.destruction_times:
            avg_time = statistics.mean(self.destruction_times)
            min_time = min(self.destruction_times)
            max_time = max(self.destruction_times)
            median_time = statistics.median(self.destruction_times)
            std_time = statistics.stdev(self.destruction_times) if len(self.destruction_times) > 1 else 0
            
            print(f'  平均时间: {avg_time:.1f}秒')
            print(f'  中位数时间: {median_time:.1f}秒')
            print(f'  最短时间: {min_time:.1f}秒')
            print(f'  最长时间: {max_time:.1f}秒')
            print(f'  标准差: {std_time:.1f}秒')
            
            # 显示每个实例的详细时间
            print(f'\n📋 各实例销毁时间详情:')
            for i, time_taken in enumerate(self.destruction_times, 1):
                print(f'  实例 {i}: {time_taken:.1f}秒')
        
        return self.destruction_times
    
    def run_full_test(self, num_instances=10):
        """运行完整的并发测试"""
        print('🎯 开始完整并发HAI实例测试')
        print('=' * 80)
        
        # 第一阶段：并发创建
        created_instances, creation_times = self.concurrent_creation_test(num_instances)
        
        # 第二阶段：并发销毁
        destruction_times = self.concurrent_destruction_test()
        
        # 最终统计
        print(f'\n🎯 测试总结')
        print('=' * 80)
        print(f'测试结束时间: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}')
        print(f'创建实例数量: {len(created_instances)}')
        print(f'创建时间记录: {len(creation_times)}')
        print(f'销毁时间记录: {len(destruction_times)}')
        
        if creation_times:
            print(f'\n✅ 并发创建时间统计:')
            print(f'  平均: {statistics.mean(creation_times):.1f}秒')
            print(f'  中位数: {statistics.median(creation_times):.1f}秒')
            print(f'  范围: {min(creation_times):.1f} - {max(creation_times):.1f}秒')
            print(f'  标准差: {statistics.stdev(creation_times) if len(creation_times) > 1 else 0:.1f}秒')
        
        if destruction_times:
            print(f'\n✅ 并发销毁时间统计:')
            print(f'  平均: {statistics.mean(destruction_times):.1f}秒')
            print(f'  中位数: {statistics.median(destruction_times):.1f}秒')
            print(f'  范围: {min(destruction_times):.1f} - {max(destruction_times):.1f}秒')
            print(f'  标准差: {statistics.stdev(destruction_times) if len(destruction_times) > 1 else 0:.1f}秒')
        
        # 计算并发效率
        if creation_times:
            total_creation_time = max(creation_times)  # 最慢的实例时间
            sequential_time = sum(creation_times)      # 如果串行执行的总时间
            efficiency = (sequential_time / total_creation_time) if total_creation_time > 0 else 0
            print(f'\n🚀 并发效率分析:')
            print(f'  并发总时间: {total_creation_time:.1f}秒')
            print(f'  串行总时间: {sequential_time:.1f}秒')
            print(f'  并发效率: {efficiency:.1f}x')
        
        return creation_times, destruction_times

def main():
    """主函数"""
    test = ConcurrentHAITest()
    test.run_full_test(10)

if __name__ == '__main__':
    main()
